import { BaseMode } from "./interface";
import { Utils } from "./util";

let util = new Utils();
export class MixinTest implements BaseMode{
    run(){
        //Mixin
        applyMixins(SmartObject, [Disposable, Activatable]);
        let smartObj = new SmartObject();
         smartObj.interact();
        // setTimeout(() => smartObj.interact(), 1000);

    }
}

// Disposable Mixin
class Disposable {
    isDisposed: boolean;
    dispose() {
        this.isDisposed = true;
    }

}

// Activatable Mixin
class Activatable {
    isActive: boolean;
    activate() {
        this.isActive = true;
    }
    deactivate() {
        this.isActive = false;
    }
}

class SmartObject implements Disposable, Activatable {
    constructor() {
         util.log(this.isActive + " : " + this.isDisposed,"SmartObject constructor")
        // setInterval(() => util.log(this.isActive + " : " + this.isDisposed,"SmartObject"), 500);
    }

    interact() {
        this.activate();
          util.log(this.isActive + " : " + this.isDisposed,"SmartObject interact")
    }

    // Disposable
    isDisposed: boolean = false;
    dispose: () => void;
    // Activatable
    isActive: boolean = false;
    activate: () => void;
    deactivate: () => void;
}

////////////////////////////////////////
// In your runtime library somewhere
////////////////////////////////////////

function applyMixins(derivedCtor: any, baseCtors: any[]) {
    baseCtors.forEach(baseCtor => {
        Object.getOwnPropertyNames(baseCtor.prototype).forEach(name => {
            derivedCtor.prototype[name] = baseCtor.prototype[name];
        });
    });
}